// -*- C++ -*-
//
//  This file is part of Siena, a wide-area event notification system.
//  See http://www.inf.usi.ch/carzaniga/siena/
//
//  Authors: Antonio Carzaniga
//  See the file AUTHORS for full details. 
//
//  Copyright (C) 2003 University of Colorado
//
//  This program is free software; you can redistribute it and/or
//  modify it under the terms of the GNU General Public License
//  as published by the Free Software Foundation; either version 2
//  of the License, or (at your option) any later version.
//
//  This program is distributed in the hope that it will be useful,
//  but WITHOUT ANY WARRANTY; without even the implied warranty of
//  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
//  GNU General Public License for more details.
//
//  You should have received a copy of the GNU General Public License
//  along with this program; if not, write to the Free Software
//  Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307,
//  USA, or send email to one of the authors.
//
//
// $Id: hash.cc,v 1.5 2010-03-11 15:16:40 carzanig Exp $
//
#include "hash.h"

namespace siena {

// I suppose I should check that sizeof(unsigned int) >= 4...
//
unsigned int P = 2147483647U; 	// P = 2^31 - 1

//
// INPUT: string = c[1]c[2]c[3] ... c[N]
// OUTPUT: c[1]*3^N + c[2]*3^(N-1) + ... + c[N-1]*3 + c[N] mod P
//
unsigned int hash_string(const char* b, const char *e) throw() {
    register unsigned int h = 0;
    for ( ; b != e; ++b) {
	h = (h << 1) + h + static_cast<unsigned char>(*b);
	if (h >= P) h %= P;
    }
    return h;
}

//
// INPUT: string = c[1]c[2]c[3] ... c[N]
// OUTPUT: c[1]*3^N + c[2]*3^(N-1) + ... + c[N-1]*3 + c[N] mod P
//
unsigned int hash_string(const char* s) throw() {
    register unsigned int h = 0; 
    for ( ; *s != '\0'; ++s) {
	h = (h << 1) + h + static_cast<unsigned char>(*s);
	if (h >= P) h %= P;
    }
    return h;
}

} // end namespace siena

